package com.lechi.iot.netty.handle;

import com.lechi.iot.netty.channel.ITcpChannel;
import com.lechi.iot.netty.channel.TcpChannelGroup;
import com.lechi.iot.netty.channel.TcpContextChannel;
import com.lechi.iot.netty.listener.TcpListener;
import com.lechi.iot.netty.message.TcpMessage;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 监听器容器，存放listener的容器
 * Netty 提供了 @Sharable 注解用于修饰 ChannelHandler，标识该 ChannelHandler 全局只有一个实例，而且会被多个 ChannelPipeline 共享
 */
@Slf4j
@Sharable
public class TcpListenerHandler extends SimpleChannelInboundHandler<TcpMessage> {

    private Map<Integer, TcpListener> listeners = new ConcurrentHashMap<>();
    private TcpChannelGroup centre;

    public TcpListenerHandler(TcpChannelGroup centre) {
        this.centre = new TcpChannelGroup();
    }

    public TcpListener addListener(int command, TcpListener listener) {
        TcpListener pre = null;
        if (hasListener(command)) {
            pre = listeners.get(command);
        }
        listeners.put(command, listener);
        return pre;
    }

    public TcpListener removeListener(int command) {
        return listeners.remove(command);
    }

    public boolean hasListener(int command) {
        return listeners.get(command) != null;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TcpMessage msg) {
        TcpListener listener = listeners.get(msg.adviceAddr()) != null ? listeners.get(msg.adviceAddr()) : listeners.get(1); //通过指令数据获取那个监听器处理报文
        if (listener != null) {
            ITcpChannel channel = centre == null ? new TcpContextChannel(ctx) : centre.get(msg.deviceGroup());
            listener.receive(channel == null ? new TcpContextChannel(ctx) : channel, msg);
        }
    }
}
